package aduros.net {

import flash.events.TimerEvent;
import flash.utils.Timer;

import com.threerings.util.Log;

import com.whirled.AbstractControl;

/** Collects functions and executes them at a fixed interval inside a doBatch. */
public class BatchInvoker
{
    protected static var log :Log = Log.getLog(BatchInvoker);

    public function BatchInvoker (ctrl :AbstractControl)
    {
        _ctrl = ctrl;
    }

    public function start (interval :int) :void
    {
        stop();

        _ops = [];

        _timer = new Timer(interval);
        _timer.addEventListener(TimerEvent.TIMER, onTick);
        _timer.start();
    }

    public function push (op :Function) :void
    {
        _ops.push(op); // Will throw NPE if you don't call start() first
    }

    /** Always call this to unload properly. */
    public function stop () :void
    {
        if (_timer != null) {
            _timer.stop();
            _timer = null;
            _ops = null;
        }
    }

    protected function onTick (event :TimerEvent) :void
    {
        if (_ops.length > 0) {
            _ctrl.doBatch(function () :void {
                for each (var op :Function in _ops) {
                    try {
                        op();
                    } catch (error :*) {
                        log.warning("Error calling batch operation", error);
                    }
                }
            });

            _ops = [];
        }
    }

    protected var _timer :Timer;

    protected var _ops :Array; // of Function

    protected var _ctrl :AbstractControl;
}

}
